from rest_framework import serializers
from goods.models import SKU
from orders.models import OrderInfo, OrderGoods
from datetime import datetime
from decimal import Decimal
from django.db import transaction
from django_redis import get_redis_connection


class CartSKUSerializer(serializers.ModelSerializer):
    count = serializers.IntegerField(read_only=True)

    class Meta:
        model = SKU
        fields = '__all__'


class OrderSettlementSerializer(serializers.Serializer):
    # max_digits 指定最大位数  decimal_places 指定保留多少位小数
    freight = serializers.DecimalField(max_digits=10, decimal_places=2)

    skus = CartSKUSerializer(many=True)


'''
{
   10:{
       freight:10.00
       count:2
       name:iphone7
   },
   11:{
       freight:10.00
       count:3
       name:iphone8
   },
}



{
    freight:10.00
   10:{
       count:2
       name:iphone7
   },
   11:{

       count:3
       name:iphone8
   },
}

'''


class SaveOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }

    def create(self, validated_data):

        # 获取用户
        user = self.context['request'].user
        # 获取支付方式和地址
        pay_method = validated_data['pay_method']
        address = validated_data['address']

        # 生成订单编号
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%09d' % user.id

        with transaction.atomic():
            save_point = transaction.savepoint()  # 生成保存点对象

            try:
                # 先初始化一个订单对象
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal(0),
                    freight=Decimal(10),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == '2' else OrderInfo.ORDER_STATUS_ENUM[
                        'UNSEND']
                )

                # 获取所有选中状态的商品
                # 建立链接
                conn = get_redis_connection('cart')

                # 从缓存中获取sku_id和count
                sku_id_count = conn.hgetall('cart_%s' % user.id)

                # 获取选中状态数据     smembers :获取集合里面的所有元素
                cart_selected = conn.smembers('cart_selected_%s' % user.id)

                # 数据构建
                cart = {}
                for sku_id in cart_selected:
                    cart[int(sku_id)] = int(sku_id_count[sku_id])
                # 查询数据对象
                # skus = SKU.objects.filter(id__in=cart.keys())

                # 遍历商品对象
                for sku in cart.keys():

                    while True:
                        sku = SKU.objects.get(id=sku_id)
                        sku_count = cart[sku.id]  # 获取购买商品的数量

                        old_stock = sku.stock  # 原始库存
                        old_sales = sku.sales  # 原始销量
                        # 判断库存
                        if sku_count > old_stock:
                            raise serializers.ValidationError('库存不足')

                        # 修改商品库存和销量
                        new_stock = old_stock - sku_count
                        new_sales = old_sales + sku_count
                        ret = SKU.objects.filter(id=sku_id, stock=old_stock).update(stock=new_stock, sales=new_sales)
                        if ret==0:
                            continue
                        # sku.stock = new_stock
                        # sku.sales = new_sales

                        # 修改spu表的总销量
                        sku.goods.sales += sku_count
                        sku.goods.save()

                        # 修改order订单表
                        order.total_count += sku_count  # 商品总数
                        order.total_amount += (sku.price * sku_count)  # 商品总价格
                        # 商品订单保存
                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=sku_count,
                            price=sku.price

                        )
                        break
                # 总价添加运费
                order.total_amount += order.freight
                order.save()
            except:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError('订单操作错误')
                # raise


            transaction.savepoint_commit(save_point)

            # 购物车缓存的删除
            conn.hdel('cart_%s' % user.id, *cart_selected)
            conn.srem('cart_selected_%s' % user.id, *cart_selected)

            # 返回订单订对象
            return order
